#ifndef _COMMOM_IPC_H_
#define _COMMOM_IPC_H_
#include <log.h>
#ifndef WIN32
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <time.h>
#include <cstring>
#include <cstdio>
#include <cstdlib>

#define UNIX_OVER_UDP_SERVER 1
#define UNIX_OVER_UDP_CLIENT 0

#define MAX_MSG_SIZE 512
#define MAX_SHM_SIZE 512
#define MAX_SOCKET_SIZE 1024 * 2
#define MAX_SOCKET_EACH_SEND_SIZE 1024

namespace mdk
{
    class MallocMem
    {
        char *pBuffer;
        int length;

    public:
        MallocMem(int byte);
        char *c_str();
        int set_buffer(char *pdata);
        int get_buffer(char *pdata);
        int size();
        virtual ~MallocMem();
    };

    class MessageData
    {
    public:
        long int m_type;
        int cmd;
        int valid_size;
        char m_buffer[MAX_MSG_SIZE];

    public:
        MessageData();
        int ImportBuffer(char *pdata);
        int ExportBuffer(char *pdata);
    };

    class Message
    {
        MessageData msg;
        int msg_id;

    public:
        Message(key_t key);
        int send_msg();
        int recv_msg(long int type);
        int set_message(MessageData *message);
        int get_message(MessageData *message);
        int delete_msg();
    };

    class ShareMemoryData
    {
    public:
        int valid_size;
        char buffer[MAX_SHM_SIZE];

    public:
        ShareMemoryData();
    };

    class ShareMemory
    {
        int shm_id;
        ShareMemoryData *shm;

    public:
        ShareMemory(key_t key);
        int get_shm(ShareMemoryData *shmptr);
        int set_shm(ShareMemoryData *shmptr);
        int delete_shm();
    };

    class Semaphore
    {
        int sem_set_id;
        union semun
        {
            int val;
            struct semid_ds *buf;
            unsigned short *array;
        } sem;

    public:
        Semaphore(key_t key, int num_sems);
        int InitSem(int index, int value);
        int WaitSem(int index);
        int SignalSem(int index);
        int DeleteSem(int index);
    };

    class SocketDataHead
    {
    public:
        int cmd;
        int valid_size;

    public:
        SocketDataHead();
    };

    class SocketData
    {
    public:
        SocketDataHead data_head;
        char buffer[MAX_SOCKET_SIZE];

    public:
        SocketData();
        int set_cmd(int cmd);
        int get_cmd();
        int set_valid_size(int valid_size);
        int get_valid_size();
        int ImportBuffer(char *pdata);
        int ExportBuffer(char *pdata);
    };

    class SocketSession
    {
        int new_fd;
        int listen_fd;
        int sock_type;
        int sock_domain;
        int sock_port;
        char *sock_ip;
        int sock_backlog;
        char *sock_path;
        int sock_path_size;
        SocketData sockdata;
        struct sockaddr_in RemoteAddr;
        struct sockaddr_in LocalAddr;
        struct sockaddr_un server_addr;
        struct sockaddr_un client_addr;
        int CommomSessionInit(int domain, int type, int backlog);
        int CommomOverTCPSend(int sockfd);
        int CommomOverTCPRecv(int sockfd);
        int CommomOverUDPSend(struct sockaddr_in *sock_addr, char *ipaddr, int port);
        int CommomOverUDPRecv(struct sockaddr_in *sock_addr);

    public:
        SocketSession(char *ipaddr, int port, int domain, int type, int backlog);
        SocketSession(int domain, int type, int backlog, char *path, int path_size);
        virtual ~SocketSession();
        int SetSocketData(SocketData *pdata);
        int GetSocketData(SocketData *pdata);
        int InitServerSocket();
        int SetNoBlock();
        int SocketAccept();
        int SocketConnect();
        int SocketSend();
        int SocketRecv();
        int SocketCloseClient();
        int SocketCloseListen();
        int SetSocketSendBufSize(int size);
        int SetSocketRecvBufSize(int size);
    };
}
#endif
#endif